package com.googlecode.animator.view.zoom
{
	import com.googlecode.animator.data.Notifications;
	import com.googlecode.animator.data.cameras.CameraVO;
	import com.googlecode.animator.data.viewports.ViewportVO;
	import com.googlecode.animator.view.viewselector.ViewSelector;
	
	import flash.events.Event;
	
	import mx.events.SliderEvent;
	
	import org.puremvc.as3.interfaces.INotification;
	import org.puremvc.as3.patterns.mediator.Mediator;

	public class ZoomControlMediator extends Mediator
	{
		/**
		 * Produces a unique number to be appended to this mediator's name.
		 */
		public static var count:int = 0;
		/**
		 * Identifier. 
		 */
		public static const NAME:String = "ZoomControlMediator";
		
		/**
		 * Constructor. 
		 * @param viewComponent
		 * 
		 */
		public function ZoomControlMediator(viewComponent:ZoomControl)
		{
			var name:String = NAME + "_" + count;
			
			super(name, viewComponent);
						
			count ++;
		}
		
		/**
		 * Triggered by PureMVC framework. 
		 * 
		 */
		override public function onRegister():void
		{
			viewRef.addEventListener(SliderEvent.CHANGE, onZoom);
			viewRef.addEventListener(SliderEvent.THUMB_RELEASE, onZoomOut);
			viewRef.addEventListener(Event.REMOVED, onZoomControlRemoved);
			
			viewRef.setThumbValueAt(0, 45);
		}
		
		/**
		 * Tidy up on removal of mediator. 
		 * 
		 */
		override public function onRemove():void
		{
			viewRef.removeEventListener(SliderEvent.CHANGE, onZoom);
			viewRef.removeEventListener(SliderEvent.THUMB_RELEASE, onZoomOut);
			viewRef.removeEventListener(Event.REMOVED, onZoomControlRemoved);
		}
		
		/**
		 * Lists notification of interests. 
		 * @return 
		 * 
		 */
		override public function listNotificationInterests():Array
		{
			var list:Array = super.listNotificationInterests();
			
			list.push(Notifications.VIEWPORT_ADDED);
			list.push(Notifications.CAMERA_ADDED);
			list.push(Notifications.VIEW_SELECTOR_CHANGED);
			
			return list;
		}
		
		/**
		 * Handles notification of interests. 
		 * @param notification
		 * 
		 */
		override public function handleNotification(notification:INotification):void
		{
			super.handleNotification(notification);

			switch(notification.getName())
			{
				case Notifications.VIEWPORT_ADDED:
				
					handleViewportAdded(notification.getBody() as ViewportVO);
					
					break;
				
				case Notifications.CAMERA_ADDED:
				
					handleCameraAdded(notification.getBody() as CameraVO);
					
					break;
				
				case Notifications.VIEW_SELECTOR_CHANGED:
				
					handleViewSelectorChange(notification.getBody() as ViewSelector);
					
					break;
					
			}
		}
		/**
		 * Handles the addition of a viewport.
		 * @param viewport
		 * 
		 */
		protected function handleViewportAdded(viewport:ViewportVO):void
		{
			if(viewport.viewportID == viewRef.viewportID)
			{
				viewRef.cameraID = viewport.currentCamera;
			}
		}
		
		/**
		 * Handles the addition of a camera. 
		 * @param camera
		 * 
		 */
		protected function handleCameraAdded(camera:CameraVO):void
		{
			// check to see if the camera is associated with this control
			if(camera.name == viewRef.cameraID)
			{
				viewRef.setThumbValueAt(0, camera.zoom / camera.zoomScale);
			}
		}
		/**
		 * Handles the changing of one viewport camera to another. The scale control needs to be set to the 
		 * incoming value. 
		 * @param vs
		 * 
		 */
		protected function handleViewSelectorChange(vs:ViewSelector):void
		{
			if(vs.viewportID == viewRef.viewportID)
			{
				var camera:CameraVO = vs.selectedItem as CameraVO;
				viewRef.setThumbValueAt(0, camera.zoom / camera.zoomScale);
				
			}
		}
		/**
		 * Triggered by the user changing the zoom setting for a viewport. 
		 * @param evt
		 * 
		 */
		protected function onZoom(evt:SliderEvent):void
		{
			facade.sendNotification(Notifications.ZOOM_CONTROL_CHANGED, evt);
		}
		
		/**
		 * Triggered by the user finalising the zoom setting for a viewport. 
		 * @param evt
		 * 
		 */
		protected function onZoomOut(evt:SliderEvent):void
		{
			facade.sendNotification(Notifications.ZOOM_CONTROL_COMPLETED, evt);
		}
		
		/**
		 * Responds the zoom control being removed. 
		 * @param evt
		 * 
		 */
		protected function onZoomControlRemoved(evt:Event):void
		{
			facade.removeMediator(getMediatorName());
		}
		/**
		 * Returns a typed reference to the ZoomControl component. 
		 * @return 
		 * 
		 */
		protected function get viewRef():ZoomControl
		{
			return viewComponent as ZoomControl;
		}
		
	}
}